<?php

require_once dirname(__FILE__) . '/../../../../Domain51UnitTest.config.php';
require_once 'Domain51/Service/Amazon/Util/Header.php';

class Domain51_Service_Amazon_Util_HeaderTest extends
    PHPUnit_Framework_TestCase
{
    public function testOutputsAssociativeArrayOfHeaderInformation() {
        $header = new Domain51_Service_Amazon_Util_Header();
        $result = $header->toArray();
        
        $this->assertTrue(is_array($result));
    }
    
    public function testReturnsRequestType() {
        $requestTypes = array('GET', 'POST', 'PUT', 'DELETE');
        $type = $requestTypes[rand(0, 3)];
        
        $header = new Domain51_Service_Amazon_Util_Header();
        $header->setType($type);
        
        $this->assertSame($type, $header->getType());
    }
    
    public function testCanStoreRegularHeaders() {
        $header = new Domain51_Service_Amazon_Util_Header();
        $header->add('Content-Type', 'text/xml');
        
        $gmDate = gmdate(DATE_RFC822);
        $header->add('Date', $gmDate);
        
        $result = $header->toArray();
        
        $this->assertTrue(isset($result['Content-Type']));
        $this->assertSame('text/xml', $result['Content-Type']);
        
        $this->assertTrue(isset($result['Date']));
        $this->assertSame($gmDate, $result['Date']);
    }
    
    public function testCanStoreAmzHeaders() {
        $aclTypes = array('private', 'public-read', 'public-read-write');
        $acl = $aclTypes[rand(0, 2)];
        
        $header = new Domain51_Service_Amazon_Util_Header();
        $header->addAmz('Acl', $acl);
        $result = $header->toArray();
        
        $this->assertTrue(isset($result['X-Amz-Acl']));
        $this->assertSame($acl, $result['X-Amz-Acl']);
    }
    
    public function testCanRetrieveIndividualHeaders() {
        $header = new Domain51_Service_Amazon_Util_Header();
        
        $gmDate = gmdate(DATE_RFC822);
        $header->add('Date', $gmDate);
        
        $result = $header->get('Date');
        $this->assertSame($gmDate, $result);
    }
    
    public function testGetReturnsNullOnUnknownHeader() {
        $header = new Domain51_Service_Amazon_Util_Header();
        $this->assertTrue(is_null($header->get('unknown')));
    }
    
    public function testStoresUrl() {
        $url = '/bucket/' . rand(1000, 2000);
        $header = new Domain51_Service_Amazon_Util_Header();
        $header->setUrl($url);
        
        $this->assertSame($url, $header->getUrl());
    }
    
    public function testCanRetrieveAllAmzHeaders() {
        $aclTypes = array('private', 'public-read', 'public-read-write');
        $acl = $aclTypes[rand(0, 2)];
        
        $header = new Domain51_Service_Amazon_Util_Header();
        $header->add('Content-Type', 'text/xml');
        $header->addAmz('Acl', $acl);
        
        $expected = array('X-Amz-Acl' => $acl);
        $this->assertSame($expected, $header->toArray('Amz'));
    }
    
    public function testCanRetrieveIndividualAmzHeaders() {
        $aclTypes = array('private', 'public-read', 'public-read-write');
        $acl = $aclTypes[rand(0, 2)];
        
        $header = new Domain51_Service_Amazon_Util_Header();
        $header->addAmz('Acl', $acl);
        
        $this->assertSame($acl, $header->getAmz('Acl'));
    }
    
    public function testToarrayRetrievesAnArrayOfHeadersWithAuthorizationHeader() {
        $config = require dirname(__FILE__) . '/HeaderTest.config.php';
        Solar::start($config);
        
        $requestTypes = array('GET', 'POST', 'PUT', 'DELETE');
        $requestType = $requestTypes[rand(0, 3)];
        
        $contentTypes = array('text/html', 'text/xml');
        $contentType = $contentTypes[rand(0, 1)];
        
        $aclTypes = array('private', 'public-read', 'public-read-write');
        $aclType = $aclTypes[rand(0, 2)];
        
        $date = date(DATE_RFC822);
        $url = '/bucket/' . rand(1000, 2000);

        $header = new Domain51_Service_Amazon_Util_Header();
        $header->setUrl($url);
        $header->setType($requestType);
        $header->add('Content-Type', $contentType);
        $header->add('Date', $date);
        $header->addAmz('Acl', $aclType);
        
        // setup expected signature
        $stringToSign = 
            "{$requestType}\n" .
            "\n" . 
            "{$contentType}\n" .
            "{$date}\n" . 
            "x-amz-acl:{$aclType}\n" .
            "$url";
        
        $secretKey = $config['Domain51_Service_Amazon_Util_AuthorizationGenerator']['secret_key'];
        $crypt = new Crypt_HMAC($secretKey, 'sha1');
        $hex = new Domain51_Util_String_Hex();
        $expectedSignature = $hex->toBase64($crypt->hash($stringToSign));
        
        $accessKey = $config['Domain51_Service_Amazon_Util_AuthorizationGenerator']['access_key'];
        $expected = array(
            'Authorization' => "AWS $accessKey:$expectedSignature",
            'Content-Type' => $contentType,
            'Date' => $date,
            'X-Amz-Acl' => $aclType,
        );
        
        
        $return = $header->toArray();
        $this->assertSame($expected, $header->toArray());
        
        Solar::stop();
    }
    
    public function testCanMatchAwsExampleOne() {
/* 
PUT /quotes/nelson HTTP/1.0
Content-Md5: c8fdb181845a4ca6b8fec737b3581d76
Content-Type: text/html
Date: Thu, 17 Nov 2005 18:49:58 GMT
X-Amz-Meta-Author: foo@bar.com
X-Amz-Magic: abracadabra 
*/
        $authGen = Solar::factory(
            'Domain51_Service_Amazon_Util_AuthorizationGenerator',
            array(
                'access_key' => "44CF9590006BF252F707",
                'secret_key' => "OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV"
            )
        );
        
        $header = new Domain51_Service_Amazon_Util_Header(
            array('authGen' => $authGen)
        );
        
        $header->setType('PUT');
        $header->setUrl('/quotes/nelson');
        $header->add('Content-Md5', 'c8fdb181845a4ca6b8fec737b3581d76');
        $header->add('Content-Type', 'text/html');
        $header->add('Date', 'Thu, 17 Nov 2005 18:49:58 GMT');
        $header->add('X-Amz-Magic', 'abracadabra'); 
        $header->add('X-Amz-Meta-Author', 'foo@bar.com');
        
        $result = $header->toArray();
        $this->assertSame(
            'AWS 44CF9590006BF252F707:jZNOcbfWmD/A/f3hSvVzXZjM2HU=',
            $result['Authorization']
        );
    }
}

?>